package controllers

import (
	"crypto/sha1"
	"encoding/xml"
	"fmt"
	"io"
	"sort"
	"strings"
	"time"

	"github.com/astaxie/beego"
)

type WechatController struct {
	beego.Controller
}

// 企业微信加密消息结构
type WXEncryptMessage struct {
	XMLName    xml.Name `xml:"xml"`
	ToUserName string   `xml:"ToUserName"`
	AgentID    string   `xml:"AgentID"`
	Encrypt    string   `xml:"Encrypt"`
}

// 企业微信明文消息结构
type WXMessage struct {
	XMLName      xml.Name `xml:"xml"`
	ToUserName   string   `xml:"ToUserName"`
	FromUserName string   `xml:"FromUserName"`
	CreateTime   int64    `xml:"CreateTime"`
	MsgType      string   `xml:"MsgType"`
	Content      string   `xml:"Content"`
	MsgId        int64    `xml:"MsgId"`
	AgentID      string   `xml:"AgentID"`
}

// 企业微信回复消息结构
type WXReply struct {
	XMLName      xml.Name `xml:"xml"`
	ToUserName   string   `xml:"ToUserName"`
	FromUserName string   `xml:"FromUserName"`
	CreateTime   int64    `xml:"CreateTime"`
	MsgType      string   `xml:"MsgType"`
	Content      string   `xml:"Content"`
}

// 验证URL
func (c *WechatController) VerifyURL() {
	// 获取参数
	signature := c.GetString("msg_signature")
	timestamp := c.GetString("timestamp")
	nonce := c.GetString("nonce")
	echostr := c.GetString("echostr")

	beego.Info("VerifyURL params:", signature, timestamp, nonce, echostr)

	// 验证参数完整性
	if signature == "" || timestamp == "" || nonce == "" || echostr == "" {
		beego.Error("Missing required parameters")
		c.Ctx.WriteString("")
		return
	}

	// 验证签名
	if !c.verifySignature(signature, timestamp, nonce, "") {
		beego.Error("Signature verification failed")
		c.Ctx.WriteString("")
		return
	}

	// 返回echostr（实际应该解密后再返回，这里简化处理）
	c.Ctx.WriteString(echostr)
	beego.Info("URL verification successful")
}

// 处理消息
func (c *WechatController) HandleMessage() {
	// 获取参数
	signature := c.GetString("msg_signature")
	timestamp := c.GetString("timestamp")
	nonce := c.GetString("nonce")

	beego.Info("HandleMessage params:", signature, timestamp, nonce)

	// 验证参数完整性
	if signature == "" || timestamp == "" || nonce == "" {
		beego.Error("Missing required parameters")
		c.Ctx.WriteString("")
		return
	}

	// 读取请求体
	body, err := io.ReadAll(c.Ctx.Request.Body)
	if err != nil {
		beego.Error("Read body error:", err)
		c.Ctx.WriteString("")
		return
	}

	beego.Info("Received message body:", string(body))

	// 解析加密消息
	var encryptMsg WXEncryptMessage
	err = xml.Unmarshal(body, &encryptMsg)
	if err != nil {
		beego.Error("XML unmarshal error:", err)
		c.Ctx.WriteString("")
		return
	}

	// 验证签名
	if !c.verifySignature(signature, timestamp, nonce, encryptMsg.Encrypt) {
		beego.Error("Signature verification failed")
		c.Ctx.WriteString("")
		return
	}

	// 解密消息（这里简化处理，实际应该使用AES解密）
	// 注意：实际生产环境需要实现完整的AES解密逻辑
	beego.Info("Encrypted content:", encryptMsg.Encrypt)

	// 模拟解密后的消息处理
	msg := &WXMessage{
		ToUserName:   encryptMsg.ToUserName,
		FromUserName: "user_" + nonce, // 模拟用户ID
		CreateTime:   c.getCurrentTimestamp(),
		MsgType:      "text",
		Content:      "这是解密后的消息内容",
		AgentID:      encryptMsg.AgentID,
	}

	beego.Info("Processed message:", msg)

	// 处理消息并回复
	reply := c.processMessage(msg)
	if reply != nil {
		// 生成回复XML
		replyXML, err := xml.Marshal(reply)
		if err != nil {
			beego.Error("XML marshal error:", err)
			c.Ctx.WriteString("")
			return
		}

		beego.Info("Reply XML:", string(replyXML))
		c.Ctx.WriteString(string(replyXML))
	} else {
		// 无回复内容
		c.Ctx.WriteString("")
	}
}

// 处理消息内容
func (c *WechatController) processMessage(msg *WXMessage) *WXReply {
	switch msg.MsgType {
	case "text":
		// 文本消息处理
		return &WXReply{
			ToUserName:   msg.FromUserName,
			FromUserName: msg.ToUserName,
			CreateTime:   c.getCurrentTimestamp(),
			MsgType:      "text",
			Content:      "已收到您的消息: " + msg.Content,
		}
	default:
		beego.Info("Unhandled message type:", msg.MsgType)
	}

	// 默认不回复
	return nil
}

// 验证签名
func (c *WechatController) verifySignature(signature, timestamp, nonce, encrypt string) bool {
	token := beego.AppConfig.String("Token")

	// 排序参数
	params := []string{token, timestamp, nonce}
	if encrypt != "" {
		params = append(params, encrypt)
	}
	sort.Strings(params)

	// 拼接字符串
	str := strings.Join(params, "")

	// 计算SHA1
	sha1Hash := sha1.New()
	sha1Hash.Write([]byte(str))
	calculatedSignature := fmt.Sprintf("%x", sha1Hash.Sum(nil))

	beego.Info("Calculated signature:", calculatedSignature, "Received signature:", signature)

	return calculatedSignature == signature
}

// 获取当前时间戳
func (c *WechatController) getCurrentTimestamp() int64 {
	return time.Now().Unix()
}

// 获取企业微信配置
func (c *WechatController) getWechatConfig() map[string]string {
	return map[string]string{
		"CorpID":         beego.AppConfig.String("CorpID"),
		"AgentID":        beego.AppConfig.String("AgentID"),
		"Secret":         beego.AppConfig.String("Secret"),
		"Token":          beego.AppConfig.String("Token"),
		"EncodingAESKey": beego.AppConfig.String("EncodingAESKey"),
	}
}
